package modelo;

import java.util.ArrayList;

import vista.VentanaPrincipal;
import fiuba.algo3.titiritero.modelo.GameLoop;
import fiuba.algo3.titiritero.modelo.ObjetoVivo;
import fiuba.algo3.titiritero.modelo.ObservadorDeGameLoop;

public class Juego implements ObjetoVivo,ObservadorDeGameLoop {
	
	final int PUNTAJE_INICIAL = 10000;
	final int PUNTAJE_DISPARO = 200;
	final int PUNTAJE_TURNO = 10;
	final int PUNTAJE_MINIMO_A_RESTAR = 50; /*en nuestro caso el objeto daniable de menor costo es la mina puntual	*/
			
	private int puntaje;
	private Tablero tablero = new Tablero();
	private GameLoop gameloop;
	private VentanaPrincipal ventana;
	
	public Juego(){
		this.ingresarPuntaje(PUNTAJE_INICIAL);
	}
	
	public boolean juegoGanado() {
		ArrayList<Nave> naves = this.tablero.obtenerListaNaves();
		boolean navesDestruidas = true;
		for (Nave unaNave: naves){
			if (!unaNave.destruida()) {
				navesDestruidas = false;
			}
		}
		return navesDestruidas;
	}

	public int obtenerPuntaje() {
		return puntaje;
	}

	public void ingresarPuntaje(int puntaje) {
		this.puntaje = puntaje;
	}
	
	public void colocarMina(Mina mina){			
		this.puntaje = puntaje - mina.obtenerCosto();
		this.tablero.agregarMina(mina); // Agregamos la mina al tablero
	}
	
	public void disparar (Posicion pos){
		this.puntaje = puntaje - PUNTAJE_DISPARO;
		this.tablero.dispararNave(pos); 
	}
	
	public boolean juegoTerminado(){
		
		if (this.puntaje<PUNTAJE_MINIMO_A_RESTAR) /*si ya no se puede realizar danio por falta de puntos, el juego termino.	*/
			return true;
		
		boolean terminado = false;
		ArrayList<Nave> listaNaves = this.tablero.obtenerListaNaves();
		
		for (Nave unaNave: listaNaves){
			if (!unaNave.destruida()){
				terminado = false;
				break;
			}
			else
				terminado = true; 
		}
		
		return terminado;
		
	}
	
	public void ingresarNaveEnTablero(Nave naveAIngresar){
		this.tablero.ingresarNave(naveAIngresar);
	}

	public Tablero obtenerTablero(){
		return this.tablero;
	}
	
	public void cargarNavesInicio() {		
		
		Nave lancha1 = new Lancha(this.generarDireccionAleatoria(),this.generarOrientacionAleatoria(),this.generarPosicionAleatoria());
		Nave lancha2 = new Lancha(this.generarDireccionAleatoria(),this.generarOrientacionAleatoria(),this.generarPosicionAleatoria());
		Nave destructor1 = new Destructor(this.generarDireccionAleatoria(),this.generarOrientacionAleatoria(),this.generarPosicionAleatoria());
		Nave destructor2 = new Destructor(this.generarDireccionAleatoria(),this.generarOrientacionAleatoria(),this.generarPosicionAleatoria());
		Nave buque = new Buque(this.generarDireccionAleatoria(),this.generarOrientacionAleatoria(),this.generarPosicionAleatoria());
		Nave rompeHielos = new RompeHielos(this.generarDireccionAleatoria(),this.generarOrientacionAleatoria(),this.generarPosicionAleatoria());
		Nave portaAviones = new PortaAviones(this.generarDireccionAleatoria(),this.generarOrientacionAleatoria(),this.generarPosicionAleatoria());
		
		this.ingresarNaveEnTablero(lancha1);
		this.ingresarNaveEnTablero(lancha2);
		this.ingresarNaveEnTablero(destructor1);
		this.ingresarNaveEnTablero(destructor2);
		this.ingresarNaveEnTablero(buque);
		this.ingresarNaveEnTablero(portaAviones);
		this.ingresarNaveEnTablero(rompeHielos);		
	}
	
	public Posicion generarPosicionAleatoria(){
				
		int fila = (int) (Math.random()*(10-1+1)+1);
		int columna = (int) (Math.random()*(10-1+1)+1);
		
		Posicion pos =new Posicion(fila,columna);		
				
		return pos;
	}
	
	public String generarOrientacionAleatoria(){
		String[] direcciones= {"norte","sur","este","oeste"};
		int indice = (int) (Math.random()*direcciones.length);		
		return direcciones[indice];
	}
	
	public String generarDireccionAleatoria(){		
		String[] direcciones= {"norte","noreste","este","sureste","sur","suroeste","oeste","noroeste"};
		int indice = (int) (Math.random()*direcciones.length);		
		return direcciones[indice]; 
	}
	
	public void ingresarGameLoop(GameLoop gloop){
		this.gameloop = gloop;
	}

	@Override
	public void vivir() {
		this.tablero.siguienteTurno();
		puntaje = puntaje - PUNTAJE_TURNO;
	}

	@Override
	public void notificarCicloFinalizado() {
				
		ArrayList<Nave> naves = new ArrayList<Nave>();
		ArrayList<BloqueDeNave> partes = new ArrayList<BloqueDeNave>();
		ArrayList<Mina> minas = new ArrayList<Mina>();
		
		naves = this.obtenerTablero().obtenerListaNaves();
		
		for(Nave nave: naves) {
			if (nave.destruida()) {
				partes = nave.obtenerPartes();
				for(BloqueDeNave bloque:partes) {
					gameloop.remover(bloque.getVista());
				}
			}
		}
		
		minas = this.obtenerTablero().obtenerListaMinas();
		
		for(Mina mina: minas) {
			if (mina.detonada()) {
				gameloop.remover(mina.getVistaMina());
			}
		}
		
		ventana.getPuntaje().setText(Integer.toString(obtenerPuntaje()));
		
		if (this.juegoTerminado()) {
			String mensaje;
			
			if (this.juegoGanado()) {
				mensaje = "Ganaste... Total: " + Integer.toString(obtenerPuntaje()); 
				ventana.getNotificador().setMensaje(mensaje);
			} else {
				mensaje = "Perdiste... = (";
				ventana.getNotificador().setMensaje(mensaje);
			}
			ventana.getNotificador().setVisible(true);
			this.gameloop.detenerEjecucion();
			System.exit(0);
		} 
	}

	public void setVentana(VentanaPrincipal ventana) {
		this.ventana = ventana;
	}
	
}
